package com.eling.elcms.travel.service.impl;

import com.eling.elcms.basedoc.model.*;
import com.eling.elcms.basedoc.model.Room.Status;
import com.eling.elcms.basedoc.service.IBusinessMessageManager;
import com.eling.elcms.basedoc.service.IPersonalInfoManager;
import com.eling.elcms.basedoc.service.IRoomManager;
import com.eling.elcms.core.AppContext;
import com.eling.elcms.core.service.impl.GenericManagerImpl;
import com.eling.elcms.ordermanager.model.ServicePoint;
import com.eling.elcms.system.model.CommonUser;
import com.eling.elcms.travel.dao.IChangeRoomDao;
import com.eling.elcms.travel.model.*;
import com.eling.elcms.travel.model.CheckIn.CheckOutStatus;
import com.eling.elcms.travel.model.RoomRegister.RoomStatus;
import com.eling.elcms.travel.model.view.ChangeRoomDetailView;
import com.eling.elcms.travel.model.view.ChangeRoomView;
import com.eling.elcms.travel.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ChangeRoomManagerImpl extends GenericManagerImpl<ChangeRoom, Long>
		implements IChangeRoomManager {

	IChangeRoomDao changeRoomDao;
	
	@Autowired
	private IRoomManager roomManager;
	
	@Autowired
	private IPersonalInfoManager personalInfoManager;
	
	@Autowired
	private IRoomPersonalInfoManager roomPersonalInfoManager;
	
	@Autowired
	private IBasePriceManager basePriceManager;
	
	@Autowired
	private IRoomRegisterManager roomRegisterManager;
	
	@Autowired
	private ICheckInManager checkInManager;
	
	@Autowired
	private IRoomPerConsumptionManager roomPerConsumptionManager;
	
	@Autowired
	private IBusinessMessageManager businessMessageManager;
	
	@Autowired
	public void setChangeRoomDao(IChangeRoomDao changeRoomDao) {
		this.dao = changeRoomDao;
		this.changeRoomDao = changeRoomDao;
	}

	@Override
	public List<ChangeRoomView> queryGroup(ChangeRoomView cond) {
		return changeRoomDao.queryGroup(cond);
	}

	@Override
	public List<ChangeRoomView> queryGroupDetail(ChangeRoomView cond) {
		return changeRoomDao.queryGroupDetail(cond);
	}

	@Override
	public List<ChangeRoom> saveAll(ChangeRoomDetailView cond) {
		List<ChangeRoom> returnList = new ArrayList<ChangeRoom>();
		ChangeRoom cr = new ChangeRoom();
		Room r = new Room();
		ServicePoint servicePoint = cond.getServicePoint();
		CommonUser operator = cond.getOperator();
		
		List<ChangeRoomView> changeRoomViews = cond.getChangeRoomViews();
		if(changeRoomViews==null){
			return null;
		}
		for(ChangeRoomView crv : changeRoomViews){
			Room croom = crv.getCroom();
			if(croom==null){
				//没有调整房型和房号
				continue;
			}
			
			cr = new ChangeRoom();
			//没有调整 就不保存新的换房记录
			if(crv.getChange() == null || !crv.getChange()){
				if(null != crv.getPkChangeRoom()){
					cr = get(Long.parseLong(crv.getPkChangeRoom()));
					//保存消费
					if(crv.getRoomPerConsumptions() != null && !crv.getRoomPerConsumptions().isEmpty() && crv.getRoomPerConsumptions().get(0) !=null){
						Set<RoomPerConsumption> roomPerConSet = new HashSet<>(roomPerConsumptionManager.save(crv.getRoomPerConsumptions()));
						cr.setRoomPerConsumptions(roomPerConSet);
					}
					//保存水电
					if(crv.getWaterElectric() != null && crv.getWaterElectric()){
						cr = saveWaterElectric(crv, cr);
					}
					save(cr);
				}
				continue;
			}
			
			r = changeRoomDao.queryRoomByRoomCode(crv.getCroom().getCode());
			if(r==null){
				continue;
			}
			//把换房后的房间置为在住房
			r.setStatus(Status.CheckIn);
			Room nowRoom = roomManager.save(r);
			//把换房前的房间置为脏房
			String roomCode = crv.getRoomCode();
			r = changeRoomDao.queryRoomByRoomCode(roomCode);
			r.setStatus(Status.Dirty);
			cr.setRoom(roomManager.save(r));
			
			if(!crv.getPkPersonalInfo().trim().equals("")){
				PersonalInfo personalInfo = personalInfoManager.get(Long.parseLong(crv.getPkPersonalInfo()));
				cr.setPersonalInfo(personalInfo);
				
				//回写入住登记中的房间信息
				RoomPersonalInfo rpi = new RoomPersonalInfo();
				rpi.setPersonalInfo(personalInfo);
				List<RoomPersonalInfo> rpiList = roomPersonalInfoManager.query(rpi);
				if(!rpiList.isEmpty()){
					rpi = rpiList.get(0);
					rpi = updateCheckIn(rpi, nowRoom);
					cr = saveChanege(rpi, crv, cr);
				}
			}
			cr.setServicePoint(servicePoint);
			cr.setOperator(operator);
			cr.setChangeRoomDate(new Date());
			returnList.add(cr);
		}
		return save(returnList);
	}
	
	/**
	 * 更新入住的房间数据和查房数据
	 * TODO 需要更新换房后的入住价
	 * @param rpi
	 * @return
	 */
	private RoomPersonalInfo updateCheckIn(RoomPersonalInfo rpi, Room rm){
		CheckIn checkIn = new CheckIn();
		checkIn.setRoomRegister(rpi.getRoomRegister());;
		List<CheckIn> ciList = checkInManager.query(checkIn);
		if(!ciList.isEmpty()){
			checkIn = ciList.get(0);
			Set<RoomPersonalInfo> rpiSet = checkIn.getCheckInImplement().getRoomPersonalInfos();
			// 该房间只有当前一个人，则只更新房间数据，不需更新查房数据
			Boolean isOne = true;
			for(RoomPersonalInfo rpInfo : rpiSet){
				if(!rpi.getPkRoomPersonalInfo().equals(rpInfo.getPkRoomPersonalInfo()) && 
						checkIn.getRoomRegister().getPkRoomRegister().equals(rpInfo.getRoomRegister().getPkRoomRegister())){
					isOne = false;
				}
			}
			if(isOne){
				rpi.getRoomRegister().setRoom(rm);
				rpi.getRoomRegister().setRoomStatus(RoomStatus.NoCheckIn);
			}else{
				Boolean flag = true;
				for(RoomPersonalInfo rpInfo : rpiSet){
					if(!rpInfo.getPkRoomPersonalInfo().equals(rpi.getPkRoomPersonalInfo())){
						if(rpInfo.getNonMemberRegister() != null && (null == rpInfo.getNonMemberRegister().getSignUpRegister().getCheckOut()
								|| !rpInfo.getNonMemberRegister().getSignUpRegister().getCheckOut())){
							flag = false;
							break;
						}
						if(rpInfo.getSignUpRegister() != null && (null == rpInfo.getSignUpRegister().getCheckOut()
								|| !rpInfo.getSignUpRegister().getCheckOut())){
							flag = false;
							break;
						}
					}
				}
				// 当旧的房间除了当前人已全部查房，则更新查房数据为已查房
				if(flag){
					checkIn.setCheckOutStatus(CheckOutStatus.CheckOut);
					checkInManager.save(checkIn);
				}else{
					Room oldRoom = checkIn.getRoomRegister().getRoom();
					oldRoom.setStatus(Status.CheckIn);
					roomManager.save(oldRoom);
				}
				rpi = saveCheckIn(rpi, checkIn, rm);
			}
		}
		return rpi;
	}
	
	private RoomPersonalInfo saveCheckIn(RoomPersonalInfo rpi, CheckIn checkIn, Room rm){
		// 推送新的房间登记数据
		RoomRegister newRR = new RoomRegister();
		RoomRegister oldRR = rpi.getRoomRegister();
		newRR.setCheckInType(oldRR.getCheckInType());
		newRR.setCheckInPrice(oldRR.getCheckInPrice());
		newRR.setWaterElectric(oldRR.getWaterElectric());
		newRR.setOperateDate(new Date());
		newRR.setOperator((CommonUser)AppContext.curUser());
		newRR.setRoom(rm);
		newRR.setRoomStatus(RoomStatus.NoCheckIn);
		newRR.setStatus(oldRR.getStatus());
		newRR = roomRegisterManager.save(newRR);
		rpi.setRoomRegister(newRR);
		
		// 推送查房数据
		CheckIn newCheckIn = new CheckIn();
		newCheckIn.setCheckInDate(checkIn.getCheckInDate());
		newCheckIn.setCheckInImplement(rpi.getCheckInImplement());
		newCheckIn.setCheckOutDate(checkIn.getCheckOutDate());
		newCheckIn.setCheckOutStatus(CheckOutStatus.NoCheckOut);
		newCheckIn.setOperator((CommonUser)AppContext.curUser());
		newCheckIn.setRegisterDate(checkIn.getRegisterDate());
		newCheckIn.setRoomRegister(newRR);
		newCheckIn.setServicePoint(checkIn.getServicePoint());
		newCheckIn.setStatus(com.eling.elcms.travel.model.CheckIn.Status.CheckIn);
		newCheckIn = checkInManager.save(newCheckIn);
		businessMessageManager.saveBusinessMessage(new BusinessMessage(TargetType.Role,TaskType.CheckOut,rpi.getCheckInImplement().getPkCIImplement()));
		return rpi;
	}
	
	private ChangeRoom saveChanege(RoomPersonalInfo rpi, ChangeRoomView crv, ChangeRoom cr){
		// 还原抄表数据
		rpi.getRoomRegister().setElectricMeter(null);
		rpi.getRoomRegister().setHotWaterMeter(null);
		rpi.getRoomRegister().setWaterMeter(null);
		rpi.getRoomRegister().setCheckOutElectricMeter(null);
		rpi.getRoomRegister().setCheckOutHotWaterMeter(null);
		rpi.getRoomRegister().setCheckOutWaterMeter(null);
		rpi.getRoomRegister().setCheckOutMeterDate(null);
		rpi.getRoomRegister().setCheckInMeterDate(null);
		// 逗比一样的拼接换房消费价格
		String descript = rpi.getDescript();
		if(null == descript){
			descript = "";
		}
		Double changeRoomFee = rpi.getChangeRoomFee();
		if(null == changeRoomFee){
			changeRoomFee = 0.00;
		}
		if(crv.getWaterElectric() != null && !crv.getWaterElectric() && crv.getCheckInColdWater() != null){
			cr = saveWaterElectric(crv, cr);
			rpi.getRoomRegister().setRoomStatus(RoomStatus.NoCheckIn);
			Double coldWater = (crv.getCheckOutColdWater() - crv.getCheckInColdWater()) * basePriceManager.getPrice().getWater();
			descript += "-{" + crv.getRoomCode() + "房间-消费冷水：" + coldWater + "元";
			changeRoomFee += coldWater;
			Double hotWater = (crv.getCheckOutHotWater() - crv.getCheckInHotWater()) * basePriceManager.getPrice().getHotWater();
			descript += "-消费热水：" + hotWater + "元";
			changeRoomFee += hotWater;
			Double electric = (crv.getCheckOutElectric() - crv.getCheckInElectric()) * basePriceManager.getPrice().getElectric();
			descript += "-消费电：" + electric + "元}-";
			changeRoomFee += electric;
		}
		if(crv.getRoomPerConsumptions() != null && !crv.getRoomPerConsumptions().isEmpty() && crv.getRoomPerConsumptions().get(0) !=null){
			descript += "-{" + crv.getRoomCode() + "-房间总消费：" + getRoomConsumption(crv.getRoomPerConsumptions()) + "元}-";
			changeRoomFee += getRoomConsumption(crv.getRoomPerConsumptions());
			Set<RoomPerConsumption> roomPerConSet = new HashSet<>(roomPerConsumptionManager.save(crv.getRoomPerConsumptions()));
			cr.setRoomPerConsumptions(roomPerConSet);
		}
		rpi.setDescript(descript);
		rpi.setChangeRoomFee(changeRoomFee);
		roomPersonalInfoManager.save(rpi);
		return cr;
	}
	
	private ChangeRoom saveWaterElectric(ChangeRoomView crv, ChangeRoom cr){
		cr.setCheckInColdWater(crv.getCheckInColdWater());
		cr.setCheckOutColdWater(crv.getCheckOutColdWater());
		cr.setCheckInHotWater(crv.getCheckInHotWater());
		cr.setCheckOutHotWater(crv.getCheckOutHotWater());
		cr.setCheckInElectric(crv.getCheckInElectric());
		cr.setCheckOutElectric(crv.getCheckOutElectric());
		return cr;
	}
	
	/** 计算房间消费费*/
	private Double getRoomConsumption(List<RoomPerConsumption> rpcsList){
		Double roomConsumption = 0.00;
		if(rpcsList == null || rpcsList.size() == 0){
			return roomConsumption;
		}else{
			for(RoomPerConsumption roomPerConsumption : rpcsList){
				roomConsumption += roomPerConsumption.getPrice() * roomPerConsumption.getNum();
			}
			return roomConsumption;
		}
	}

	@Override
	public String ajaxRoomCode(ChangeRoomView cond) {
		Room queryRoomByRoomCode = changeRoomDao.queryRoomByRoomCode(cond.getCroom().getCode());
		if(queryRoomByRoomCode==null){
			return "failure";
		}
		return "success";
	}

	/**
	 * 根据联系人搜索
	 */
	@Override
	public List<ChangeRoomView> searchname(ChangeRoomView cond) {
		return changeRoomDao.searchname(cond);
	}

}
